package com.zbkj.service.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zbkj.dal.base.constants.BalanceRecordConstants;
import com.zbkj.dal.base.constants.Constants;
import com.zbkj.dal.base.constants.OrderConstants;
import com.zbkj.dal.base.constants.ProductConstants;
import com.zbkj.dal.base.enums.*;
import com.zbkj.dal.base.enums.merchant.MerOrderApptType;
import com.zbkj.dal.base.enums.show.EnumShowVO;
import com.zbkj.dal.base.page.CommonPage;
import com.zbkj.dal.common.enums.ExpressType;
import com.zbkj.dal.common.exception.CrmebException;
import com.zbkj.dal.common.utils.CrmebUtil;
import com.zbkj.dal.common.utils.DateConverter;
import com.zbkj.dal.dao.ShareMapper;
import com.zbkj.dal.entity.ba.BizImg;
import com.zbkj.dal.entity.ba.Share;
import com.zbkj.dal.entity.merchant.Merchant;
import com.zbkj.dal.entity.merchant.MerchantOrderAppointment;
import com.zbkj.dal.entity.order.OrderAddress;
import com.zbkj.dal.entity.order.OrderInvoice;
import com.zbkj.dal.entity.order.UserDuesRecord;
import com.zbkj.dal.entity.product.*;
import com.zbkj.dal.entity.user.User;
import com.zbkj.dal.entity.user.UserAddress;
import com.zbkj.dal.pojo.request.OrderSendRequest;
import com.zbkj.dal.pojo.request.PageParamRequest;
import com.zbkj.dal.pojo.request.ShareQueryRequest;
import com.zbkj.dal.pojo.request.ba.ConcludeShareRequest;
import com.zbkj.dal.pojo.request.ba.UpdateFinalResultRequest;
import com.zbkj.dal.pojo.request.ba.UpdateInitialResultRequest;
import com.zbkj.dal.pojo.response.MerchantAddressVO;
import com.zbkj.dal.pojo.response.OrderInvoiceResponse;
import com.zbkj.dal.pojo.response.UserAddressVO;
import com.zbkj.dal.pojo.response.UserInfoResponse;
import com.zbkj.dal.pojo.response.ba.MyShareResponse;
import com.zbkj.dal.pojo.response.ba.ShareDetailResponse;
import com.zbkj.dal.pojo.response.ba.ShareOrderCancelResponse;
import com.zbkj.dal.pojo.response.ba.ShareResponse;
import com.zbkj.dal.pojo.vo.LogisticsResultVo;
import com.zbkj.service.manager.ExpressManager;
import com.zbkj.service.manager.QuotaManager;
import com.zbkj.service.manager.ShareProfitManager;
import com.zbkj.service.model.dto.address.OrderAddressCreateDTO;
import com.zbkj.service.model.dto.express.CreateExpressDTO;
import com.zbkj.service.model.dto.order.OrderMerAppointmentDTO;
import com.zbkj.service.model.front.req.log.ShareOrderLogCreateReq;
import com.zbkj.service.model.front.req.recycle.SupplyApplyCancelReq;
import com.zbkj.service.model.front.req.recycle.SupplyApplyReq;
import com.zbkj.service.model.front.vo.log.ShareOrderLogVO;
import com.zbkj.service.service.*;
import com.zbkj.service.service.merchant.MerchantOrderAppointmentService;
import com.zbkj.service.service.order.ShareOrderOperateLogService;
import com.zbkj.service.util.UserUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 奢品共享 服务实现类
 * </p>
 *
 * @author jhui
 * @since 2023-10-03
 */
@Service
public class ShareServiceImpl extends ServiceImpl<ShareMapper, Share> implements ShareService {

    @Autowired
    private UserService userService;
    @Autowired
    private UserAddressService userAddressService;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private ProductService productService;
    @Autowired
    private ProductAttrService attrService;
    @Autowired
    private ProductAttrValueService productAttrValueService;
    @Autowired
    private ProductDescriptionService productDescriptionService;
    @Autowired
    private BizImgService bizImgService;
    @Autowired
    private UserDuesRecordService userDuesRecordService;
    @Resource
    private ShareOrderOperateLogService shareOrderOperateLogService;
    @Resource
    private MerchantOrderAppointmentService merchantOrderAppointmentService;
    @Autowired
    private MerchantService merchantService;
    @Autowired
    private QuotaManager quotaManager;
    @Autowired
    private ShareProfitManager shareProfitManager;
    @Autowired
    private ProductBrandService productBrandService;
    @Value("${spring.tencent.url}")
    private String tencentUrl;
    @Autowired
    private OrderInvoiceService orderInvoiceService;
    @Autowired
    private OrderAddressService orderAddressService;
    @Resource
    private OrderService orderService;
    @Autowired
    private ExpressManager expressManager;
    @Value("${customer.service.default-merchant-id}")
    private Integer defaultMerchantId;

    @Override
    public CommonPage<MyShareResponse> listMyShare(String status, PageParamRequest pageParamRequest) {
        Integer userId = userService.getUserIdException();
        LambdaQueryWrapper<Share> queryWrapper = Wrappers.lambdaQuery(Share.class);
        queryWrapper.eq(Share::getUid, userId);
        if (StringUtils.isNotEmpty(status)) {
            queryWrapper.eq(Share::getStatus, status);
        }
        queryWrapper.orderByDesc(Share::getId);
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<Share> pageList = list(queryWrapper);
        PageInfo<Share> sharePageInfo = PageInfo.of(pageList);
        if (CollectionUtils.isEmpty(sharePageInfo.getList())) {
            return CommonPage.empty(pageParamRequest.getLimit());
        }
        List<Share> list = sharePageInfo.getList();
        // 获取图片信息
        List<Integer> ids = list.stream().map(Share::getId).distinct().collect(Collectors.toList());
        List<BizImg> bizImgs = bizImgService.listByBizIdsAndPosition(Lists.newArrayList(BizTypeEnum.SHARE.getType(), BizTypeEnum.RECYCLE.getType()), ids, RecyclePositionEnums.POSITIVE);
        Map<Integer, String> imgMapping = bizImgs.stream().collect(Collectors.toMap(BizImg::getBizId, BizImg::getPath));
        List<MyShareResponse> responses = list.stream().map(share -> {
            String tips = getShareTipsForFrontApi(share.getOrderNo(), share);
            MyShareResponse myShareResponse = MyShareResponse.buildByShare(share, imgMapping.getOrDefault(share.getId(), StringUtils.EMPTY), tips);
            ProductBrand brand = productBrandService.getById(StringUtils.isEmpty(share.getBrandFinal()) ? share.getBrand() : share.getBrandFinal());
            String productName = brand.getName() + ProductTypeEnums.valueOf(share.getProductType()).getDesc();
            myShareResponse.setProductName(productName);
            return myShareResponse;
        }).collect(Collectors.toList());
        return CommonPage.restPage(CommonPage.copyPageInfo(sharePageInfo, responses));
    }

    @Override
    public Boolean deleteMyShare(Integer id) {
        Integer userId = userService.getUserIdException();
        LambdaQueryWrapper<Share> queryWrapper = Wrappers.lambdaQuery(Share.class);
        queryWrapper.eq(Share::getId, id).eq(Share::getStatus, 0).eq(Share::getUid, userId);
        return this.remove(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ShareOrderCancelResponse cancel(SupplyApplyCancelReq req) {
        // 更新供享订单信息
        Integer userId = userService.getUserIdException();
        Share share = getByOrderNo(req.getOrderNo());
        if (Objects.isNull(share)) {
            throw new CrmebException("该订单不存在");
        }
        Assert.isTrue(Objects.equals(userId, share.getUid()), "该订单不存在");
        if (!Objects.equals(share.getStatus(), BizSharedOrderStatus.COMPLETED.name())) {
            throw new CrmebException("该订单状态不能取消");
        }
        // 获取商品名称
        String brand = share.getBrand();
        ProductBrand brand1 = productBrandService.getById(brand);
        String productName = brand1.getName() + ProductTypeEnums.valueOf(share.getProductType()).getDesc();
        // 供享取消
        ShareOrderCancelResponse shareOrderCancelResponse = new ShareOrderCancelResponse();
        shareOrderCancelResponse.setReturnType(req.getReturnType());
        // 如果是物流，需要创建物流，并且下单
        if (Objects.equals(SupplyApplyCancelReq.ReturnType.EXPRESS.getCode(), req.getReturnType())) {
            // 收方地址
            UserAddress userAddress = userAddressService.getById(req.getUserAddressId());
            Assert.notNull(userAddress, "收货地址不存在");
            orderAddressService.insertAddress(req.getOrderNo(), OrderAddressType.RECEIVER, ExpressOrderType.SHARED_CANCEL, OrderAddressCreateDTO.buildByUserAddress(userAddress));
            // 寄方地址
            Merchant merchant = merchantService.getShareServiceMerchant();
            Assert.notNull(merchant, "总店地址不存在");
            orderAddressService.insertAddress(req.getOrderNo(), OrderAddressType.SHIPPER, ExpressOrderType.SHARED_CANCEL, OrderAddressCreateDTO.buildByMerchantAddress(merchant));
            // 创建一个物流订单
            CreateExpressDTO expressOrder = expressManager.createExpressOrder(req.getOrderNo(), productName, ExpressOrderPayMethodType.SHIPPER_PAY, ExpressOrderType.SHARED_CANCEL);
            // 创建一个订单信息
            OrderInvoice orderInvoice = new OrderInvoice();
            orderInvoice.setOrderNo(req.getOrderNo());
            orderInvoice.setExpressOrderNo(expressOrder.getExpressOrder());
            orderInvoice.setExpressOrderType(ExpressOrderType.SHARED_CANCEL.name());
            orderInvoice.setMerId(defaultMerchantId);
            orderInvoice.setUid(share.getUid());
            orderInvoice.setTrackingNumber(expressOrder.getExpressNumber());
            orderInvoice.setExpressName(ExpressType.SF.getName());
            orderInvoice.setExpressCode(ExpressType.SF.getCode());
            orderInvoice.setTotalNum(1);
            orderInvoice.setStatus(OrderInvoceStatus.WAITING.getCode());
            orderInvoice.setCreateTime(LocalDateTime.now());
            orderInvoice.setUpdateTime(LocalDateTime.now());
            orderInvoiceService.save(orderInvoice);
            // 返回信息
            shareOrderCancelResponse.setUserAddress(UserAddressVO.buildByUserAddress(userAddress));
            // 到店自提
            share.setSubStatus(BizSharedOrderStatus.SubStatus.RETURNED_PICKUP.name());
        }
        // 如果是上门，则需要创建上门预约信息
        if (Objects.equals(SupplyApplyCancelReq.ReturnType.PICKUP.getCode(), req.getReturnType())) {
            OrderMerAppointmentDTO appointment = merchantOrderAppointmentService.createMerchantOrderAppointmentWithLongTime(req.getOrderNo(), defaultMerchantId, share.getUid(), MerOrderApptType.RENT_RETURN);
            Merchant merchant = merchantService.getShareServiceMerchant();
            shareOrderCancelResponse.setMerchantAddress(MerchantAddressVO.buildByMerchant(merchant));
            shareOrderCancelResponse.setPickupCode(appointment.getApptNumber());
            // 待物流收货
            share.setSubStatus(BizSharedOrderStatus.SubStatus.RETURNED_EXPRESS.name());
        }
        // 状态
        share.setStatus(BizSharedOrderStatus.RETURNED.name());
        this.updateById(share);
        return shareOrderCancelResponse;
    }

    @Override
    public Boolean create(SupplyApplyReq req) {
        if (req.getDescription().length() > 200) {
            throw new CrmebException("描述不能超过200字");
        }
        Integer userId = userService.getUserIdException();
        Share share = new Share();
        share.setUid(userId);
        share.setMerId(defaultMerchantId);
        share.setOrderNo(CrmebUtil.getOrderNo(OrderConstants.USER_SUPPLY_ORDER_PREFIX));
        share.setBrand(req.getBrand());
        share.setCode(req.getModel());
        share.setShareMode(req.getSupplyType());
        share.setProductType(req.getProductType());
        share.setQuality(req.getQuality());
        share.setParts(CollUtil.join(req.getParts(), ","));
        share.setDescription(req.getDescription());
        share.setStatus(BizSharedOrderStatus.PENDING_ASSESSMENT.name());
        share.setCreateTime(LocalDateTime.now());
        share.setUpdateTime(LocalDateTime.now());
        return transactionTemplate.execute((e) -> {
            save(share);
            List<BizImg> bizImgs = req.getProductUrls().stream().map(m -> {
                String url = m.getUrl().replaceAll(tencentUrl, "").replaceFirst("/", "");
                return SupplyApplyReq.generateBizImg(share.getId(), url, m.getType());
            }).collect(Collectors.toList());
            bizImgService.saveBatch(bizImgs);
            return Boolean.TRUE;
        });
    }

    @Override
    public List<EnumShowVO<String>> getOrderStatusList() {
        List<EnumShowVO<String>> statusList = new ArrayList<>();
        for (BizSharedOrderStatus value : BizSharedOrderStatus.values()) {
            EnumShowVO<String> vo = new EnumShowVO<>();
            vo.setCode(value.name());
            vo.setDesc(value.getText());
            statusList.add(vo);
        }
        return statusList;
    }

    @Override
    public PageInfo<ShareResponse> querySharesPaged(Integer merId, ShareQueryRequest shareQueryRequest, PageParamRequest pageParamRequest) {
        LambdaQueryWrapper<Share> queryWrapper = Wrappers.lambdaQuery(Share.class);
        queryWrapper.eq(Objects.nonNull(merId), Share::getMerId, merId);

        if (StringUtils.isNotEmpty(shareQueryRequest.getOrderNo())) {
            queryWrapper.eq(Share::getOrderNo, shareQueryRequest.getOrderNo());
        }
        if (shareQueryRequest.getStatus() != null) {
            queryWrapper.in(Share::getStatus, shareQueryRequest.getStatus());
        }
        if (StringUtils.isNotEmpty(shareQueryRequest.getCategory())) {
            queryWrapper.like(Share::getProductTypeFinal, "%" + shareQueryRequest.getCategory() + "%");
        }
        if (StringUtils.isNotEmpty(shareQueryRequest.getBrand())) {
            queryWrapper.like(Share::getBrandFinal, "%" + shareQueryRequest.getBrand() + "%");
        }
        queryWrapper.orderByDesc(Share::getId);
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<Share> list = this.list(queryWrapper);
        PageInfo<Share> pageInfo = PageInfo.of(list);

        PageInfo<ShareResponse> result = new PageInfo<>();
        result.setPages(pageInfo.getPages());
        result.setPageNum(pageInfo.getPageNum());
        result.setPageSize(pageInfo.getPageSize());
        result.setTotal(pageInfo.getTotal());
        List<ShareResponse> dtos = Lists.newArrayList();
        for (Share share : pageInfo.getList()) {
            ShareResponse shareResponse = new ShareResponse();
            BeanUtils.copyProperties(share, shareResponse);
            shareResponse.setShareModeName(BizShareModeEnum.toName(share.getShareMode()));
            shareResponse.setStatusDesc(BizSharedOrderStatus.text(share.getStatus()));
            shareResponse.setOrderTime(share.getCreateTime());
            dtos.add(shareResponse);
            // ToDo 退回方式
        }
        result.setList(dtos);
        UserUtils.fillUsers(dtos);
//        if (CollectionUtils.isNotEmpty(dtos)) {
//            List<Integer> operatorIds = dtos.stream().filter(p -> p.getOperatorId() != null).map(m -> m.getOperatorId()).distinct().collect(Collectors.toList());
//            if (CollectionUtils.isNotEmpty(operatorIds)) {
//                Map<Integer, String> nameMapByIdList = adminService.getNameMapByIdList(operatorIds);
//                for (ShareResponse dto : dtos) {
//                    if (dto.getOperatorId() != null) {
//                        dto.setOperatorName(nameMapByIdList.get(dto.getOperatorId()));
//                    }
//                }
//            }
//        }
        return result;
    }

    @Override
    public boolean conclude(ConcludeShareRequest concludeShareRequest) {
        LambdaUpdateWrapper<Share> updateWrapper = Wrappers.lambdaUpdate(Share.class);
        updateWrapper
                .set(Share::getCode, concludeShareRequest.getCode())
                .set(Share::getStatus, concludeShareRequest.getStatus())
                .set(Share::getRemark, concludeShareRequest.getRemark())
                .set(Share::getOperatorId, concludeShareRequest.getOperatorId())
                .set(Share::getEstimatePriceFinal, concludeShareRequest.getEstimatePrice())
                .set(Share::getUpdateTime, LocalDateTime.now())
                .set(Share::getShareMode, concludeShareRequest.getShareMode())
                .eq(Share::getId, concludeShareRequest.getId());
        boolean result = this.update(updateWrapper);
        if (result && concludeShareRequest.getStatus() == 1) {
            Share share = getById(concludeShareRequest.getId());
            User user = userService.getById(share.getUid());
            // 会员获得会费额度
            BigDecimal addPrice = concludeShareRequest.getEstimatePrice();
            BigDecimal balance = user.getDuesAmount().add(addPrice);
            BigDecimal creditBalance = user.getCreditAmount().add(addPrice);

            UserDuesRecord userDuesRecord = new UserDuesRecord();
            userDuesRecord.setUid(share.getUid());
            userDuesRecord.setLinkId(share.getId().toString());
            userDuesRecord.setLinkType(BalanceRecordConstants.BALANCE_RECORD_LINK_TYPE_SHARE);
            userDuesRecord.setType(BalanceRecordConstants.BALANCE_RECORD_TYPE_ADD);
            userDuesRecord.setAmount(addPrice);
            userDuesRecord.setBalance(balance);
            userDuesRecord.setCreditAmount(addPrice);
            userDuesRecord.setCreditBalance(creditBalance);
            userDuesRecord.setRemark(StrUtil.format(BalanceRecordConstants.BALANCE_RECORD_REMARK_RECHARGE, addPrice));
            userDuesRecordService.save(userDuesRecord);

            // 用户余额
            userService.updateDuesMoney(share.getUid(), addPrice, Constants.OPERATION_TYPE_ADD);
        }
        return result;
    }

    @Override
    public boolean createProduct(Integer id) {
        Share share = this.getById(id);

        if (share.getEstimatePriceFinal() == null) {
            new CrmebException("评估价格为空，不能创建商品");
        }

        // product部分
        Product product = new Product();
        product.setId(null);
        product.setMerId(3);
        product.setPrice(share.getEstimatePriceFinal());
        product.setOtPrice(share.getEstimatePriceFinal());
        product.setCost(share.getEstimatePriceFinal());
        product.setStock(1);
        product.setRentPrice(share.getEstimatePriceFinal());
        if (BizShareModeEnum.isVal(share.getShareMode())) {
            product.setOwnerUid(share.getUid());
        }

        product.setAuditStatus(ProductConstants.AUDIT_STATUS_EXEMPTION);
        product.setIsAudit(false);
        product.setIsShow(false);

        // 轮播图片
        List<String> slideImgs = Lists.newArrayList();
        List<BizImg> bizImgs = bizImgService.listByBizId(BizTypeEnum.SHARE.getType(), id);
        if (CollectionUtils.isNotEmpty(bizImgs)) {
            product.setImage(bizImgs.get(0).getPath());
            for (BizImg bizImg : bizImgs) {
                slideImgs.add(bizImg.getPath());
            }
        } else {
            slideImgs.add("");
        }
        product.setSliderImage(JSON.toJSONString(slideImgs));


        // attr部分
        List<ProductAttr> attrAddList = CollUtil.newArrayList();

        ProductAttr attr = new ProductAttr();
        attr.setAttrName(ProductConstants.SINGLE_ATTR_NAME);
        attr.setType(ProductConstants.PRODUCT_TYPE_NORMAL);
        attr.setAttrValues(ProductConstants.PRODUCT_TYPE_NORMAL_STR);
        attr.setIsDel(false);
        attrAddList.add(attr);


        // attrValue部分
        List<ProductAttrValue> attrValueAddList = CollUtil.newArrayList();
        ProductAttrValue attrValue = new ProductAttrValue();

        attrValue.setId(null);
        attrValue.setSku((ProductConstants.PRODUCT_TYPE_NORMAL_STR));
        attrValue.setStock(1);
        attrValue.setSales(0);
        attrValue.setPrice(product.getPrice());
//        attrValue.setImage(systemAttachmentService.clearPrefix(e.getImage(), cdnUrl));
        attrValue.setCost(product.getCost());
        attrValue.setOtPrice(product.getOtPrice());
        attrValue.setWeight(BigDecimal.ZERO);
        attrValue.setVolume(BigDecimal.ZERO);
        attrValue.setBrokerage(0);
        attrValue.setBrokerageTwo(0);
        attrValue.setVersion(0);
        attrValue.setProductId(product.getId());
        attrValue.setQuota(0);
        attrValue.setQuotaShow(0);
        attrValue.setType(ProductConstants.PRODUCT_TYPE_NORMAL);
        HashMap<Object, Object> valueAddMap = Maps.newHashMap();
        valueAddMap.put(ProductConstants.SINGLE_ATTR_NAME, ProductConstants.PRODUCT_TYPE_NORMAL_STR);
        attrValue.setAttrValue(JSON.toJSONString(valueAddMap));
        attrValueAddList.add(attrValue);
        // 处理富文本
        ProductDescription spd = new ProductDescription();
        spd.setDescription("");
        spd.setType(ProductConstants.PRODUCT_TYPE_NORMAL);

        Boolean execute = transactionTemplate.execute(e -> {
            productService.save(product);

            if (CollUtil.isNotEmpty(attrAddList)) {
                attrAddList.forEach(item -> item.setProductId(product.getId()));
                attrService.saveBatch(attrAddList);
            }
            if (CollUtil.isNotEmpty(attrValueAddList)) {
                attrValueAddList.forEach(item -> item.setProductId(product.getId()));
                productAttrValueService.saveBatch(attrValueAddList);
            }

            spd.setProductId(product.getId());
            productDescriptionService.deleteByProductId(product.getId(), ProductConstants.PRODUCT_TYPE_NORMAL);
            productDescriptionService.save(spd);

            share.setProductId(product.getId());
            this.modifyShareProduct(share);
            return Boolean.TRUE;
        });
        return execute;
    }

    @Override
    public ShareDetailResponse detail(String orderNo, Integer userId) {
        LambdaQueryWrapper<Share> lqw = Wrappers.lambdaQuery();
        lqw.eq(Share::getOrderNo, orderNo);
        if (Objects.nonNull(userId)) {
            lqw.eq(Share::getUid, userId);
        }
        Share share = this.getOne(lqw);
        if (Objects.isNull(share)) {
            return null;
        }
        // 获取图片并且进行排序
        Map<RecyclePositionEnums, BizImg> bizImgs = bizImgService.listByBizId(BizTypeEnum.SHARE.getType(), share.getId()).stream()
                .collect(Collectors.toMap(img -> RecyclePositionEnums.valueOf(img.getPosition()), Function.identity()));
        // -------------------------------------- 构建Tips字段 --------------------------------------
        String tips = getShareTipsForFrontApi(orderNo, share);
        ShareDetailResponse shareDetailResponse = ShareDetailResponse.buildByShare(share, bizImgs, tips);
        // 设置用户提交品牌信息
        String brand = share.getBrand();
        ProductBrand brand1 = productBrandService.getById(brand);
        shareDetailResponse.getUserSubmit().setBrand(brand1.getName());
        // 设置初评提交的品牌信息
        String brandFinal = share.getBrandFinal();
        if (StringUtils.isNotEmpty(brandFinal)) {
            if (StringUtils.equals(brand, brandFinal)) {
                shareDetailResponse.getInitialEvaluation().setBrand(brand1.getName());
                shareDetailResponse.setProductName(brand1.getName() + ProductTypeEnums.valueOf(share.getProductType()).getDesc());
            } else {
                ProductBrand brand2 = productBrandService.getById(brandFinal);
                shareDetailResponse.getInitialEvaluation().setBrand(brand2.getName());
                shareDetailResponse.setProductName(brand2.getName() + ProductTypeEnums.valueOf(share.getProductType()).getDesc());
            }
        }

        // 获取总店的商户地址
        Merchant merchant = merchantService.getShareServiceMerchant();

        // ----------------------------------------- 设置预约(取件、到店)信息 -----------------------------------------
        if (Objects.equals(BizSharedOrderStatus.PENDING_VALUATION.name(), share.getStatus())
                && Objects.equals(BizSharedOrderStatus.SubStatus.WAITING_USER_PICKUP.name(), share.getSubStatus())) {
            MerchantOrderAppointment appointment = merchantOrderAppointmentService.findAppointmentByOrderId(share.getOrderNo(), MerOrderApptType.SHARED_CREATE);
            ShareDetailResponse.InStoreAppt inStoreAppt = new ShareDetailResponse.InStoreAppt();
            inStoreAppt.setReservationNo(appointment.getApptCode());
            inStoreAppt.setName(merchant.getName());
            inStoreAppt.setPhone(merchant.getPhone());
            inStoreAppt.setAddress(merchant.getProvince() + merchant.getCity() + merchant.getDistrict() + merchant.getAddressDetail());
            inStoreAppt.setLatitude(merchant.getLatitude());
            inStoreAppt.setLongitude(merchant.getLongitude());
            inStoreAppt.setDateDesc(DateConverter.convertDate(appointment.getApptDate()));
            inStoreAppt.setStartTime(appointment.getApptTimeStart());
            inStoreAppt.setEndTime(appointment.getApptTimeEnd());
            shareDetailResponse.setInStoreAppt(inStoreAppt);
        } else if (Objects.equals(BizSharedOrderStatus.PENDING_VALUATION.name(), share.getStatus())
                && Objects.equals(BizSharedOrderStatus.SubStatus.PENDING_EXPRESS_DELIVERY.name(), share.getSubStatus())) {
            // 物流订单信息
            OrderInvoiceResponse orderInvoiceResponse = orderInvoiceService.findOneByOrderNoAndOrderType(orderNo, ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV);
            // 订单地址信息
            OrderAddress address = orderAddressService.getOneOrderAddressList(orderNo, OrderAddressType.SHIPPER, ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV);
            // 组成数据
            ShareDetailResponse.PickUpAppt pickUpAppt = new ShareDetailResponse.PickUpAppt();
            pickUpAppt.setId(orderInvoiceResponse.getId());
            pickUpAppt.setDeliveryName(orderInvoiceResponse.getExpressName());
            pickUpAppt.setPickupCode(orderInvoiceResponse.getPickupCode());
            pickUpAppt.setSenderName(address.getContactName());
            pickUpAppt.setSenderPhone(address.getContactPhone());
            pickUpAppt.setSenderAddress(address.getProvinceName() + address.getCityName() + address.getRegionName() + address.getAddress());
            pickUpAppt.setDateDesc(DateConverter.convertDate(orderInvoiceResponse.getPickupTime().toLocalDate()));
            pickUpAppt.setStartTime(orderInvoiceResponse.getPickupTime().toLocalTime());
            pickUpAppt.setEndTime(orderInvoiceResponse.getPickupTime().toLocalTime().plusHours(2));
            shareDetailResponse.setPickUpAppt(pickUpAppt);
        }

        // ----------------------------------------- 设置物流轨迹信息 -----------------------------------------
        shareDetailResponse.setOrderLogisticsResponse(orderInvoiceService.findTraceByOrderNoAndLastTraceOnly(orderNo));
        // ----------------------------------------- 设置最终评价结果 -----------------------------------------
        if (Objects.nonNull(share.getEstimatePriceFinal())) {
            ShareDetailResponse.FinalEstimation finalEstimation = new ShareDetailResponse.FinalEstimation();
            finalEstimation.setEstimation(share.getEstimatePriceFinal().toPlainString());
            finalEstimation.setBalance(share.getEstimatePriceFinal().multiply(BigDecimal.valueOf(0.05)).setScale(2, RoundingMode.DOWN).toPlainString());
//            finalEstimation.setFinalDescription();
            shareDetailResponse.setFinalEstimation(finalEstimation);
        }
        // ----------------------------------------- 设置完成时间 -----------------------------------------
        ShareOrderLogVO confirmFinal = shareOrderOperateLogService.getOneLog(orderNo, ShareOrderLogTypeEnums.CONFIRM_FINAL_EVALUATION);
        if (Objects.nonNull(confirmFinal)) {
            shareDetailResponse.setCompletedTime(confirmFinal.getOperateTime());
        }
        // todo 添加初评结果 和终评结果

        return shareDetailResponse;
    }

    private String getShareTipsForFrontApi(String orderNo, Share share) {
        String tips = "";
        if (Objects.equals(BizSharedOrderStatus.PENDING_SHIPMENT.name(), share.getStatus())) {
            // 初评时间 + 72 H
            ShareOrderLogVO logVO = shareOrderOperateLogService.getOneLog(orderNo, ShareOrderLogTypeEnums.SUBMIT_EVALUATION);
            tips = String.format(BizSharedOrderStatus.PENDING_SHIPMENT.getTemplate(), logVO.getOperateTime().plusHours(72).format(DatePattern.NORM_DATETIME_FORMATTER));
        } else if (Objects.equals(BizSharedOrderStatus.PENDING_VALUATION.name(), share.getStatus())) {
            // 用户确认初评时间
            ShareOrderLogVO logVO = shareOrderOperateLogService.getOneLog(orderNo, ShareOrderLogTypeEnums.SUBMIT_EVALUATION);
            tips = String.format(BizSharedOrderStatus.PENDING_VALUATION.getTemplate(), logVO.getOperateTime().format(DatePattern.NORM_DATETIME_FORMATTER));
        } else if (Objects.equals(BizSharedOrderStatus.VALUATION.name(), share.getStatus())) {
            // 估价中
            ShareOrderLogVO logVO = shareOrderOperateLogService.getOneLog(orderNo, ShareOrderLogTypeEnums.PLAT_CONFIRM_RECEIPT);
            tips = String.format(BizSharedOrderStatus.VALUATION.getTemplate(), logVO.getOperateTime().format(DatePattern.NORM_DATETIME_FORMATTER));
        } else if (Objects.equals(BizSharedOrderStatus.PENDING_VALUATION_CONFIRMATION.name(), share.getStatus())) {
            // 用户确认最终估价
            ShareOrderLogVO logVO = shareOrderOperateLogService.getOneLog(orderNo, ShareOrderLogTypeEnums.SUBMIT_FINAL_EVALUATION);
            tips = String.format(BizSharedOrderStatus.PENDING_VALUATION_CONFIRMATION.getTemplate(), logVO.getOperateTime().plusHours(24).format(DatePattern.NORM_DATETIME_FORMATTER));
        } else if (Objects.equals(BizSharedOrderStatus.BEING_RETURNED.name(), share.getStatus())) {
            // 退回中
            tips = BizSharedOrderStatus.BEING_RETURNED.getTemplate();
        } else if (Objects.equals(BizSharedOrderStatus.RETURNED.name(), share.getStatus())) {
            // 退回中
            ShareOrderLogVO logVO = shareOrderOperateLogService.getOneLog(orderNo, ShareOrderLogTypeEnums.RETURNED_SHIPMENT);
            tips = String.format(BizSharedOrderStatus.BEING_RETURNED.getTemplate(), logVO.getOperateTime().format(DatePattern.NORM_DATETIME_FORMATTER));
        }
        return tips;
    }

    @Override
    public Share getByProductId(Integer productId) {
        LambdaQueryWrapper<Share> queryWrapper = Wrappers.lambdaQuery(Share.class);
        queryWrapper.eq(Share::getProductId, productId)
                .eq(Share::getStatus, 1);
        return getOne(queryWrapper);
    }

    @Override
    public Share getByOrderNo(String orderNo) {
        LambdaQueryWrapper<Share> queryWrapper = Wrappers.lambdaQuery(Share.class);
        queryWrapper.eq(Share::getOrderNo, orderNo);
        return getOne(queryWrapper);
    }

    private void modifyShareProduct(Share share) {
        LambdaUpdateWrapper<Share> updateWrapper = Wrappers.lambdaUpdate(Share.class);
        updateWrapper.set(Share::getProductId, share.getProductId())
                .eq(Share::getId, share.getId());
        update(updateWrapper);
    }

    /**
     * 商品sku
     *
     * @param attrValue json字符串
     * @return sku
     */
    private String getSku(String attrValue) {
        LinkedHashMap<String, String> linkedHashMap = JSONObject.parseObject(attrValue, LinkedHashMap.class, Feature.OrderedField);
        Iterator<Map.Entry<String, String>> iterator = linkedHashMap.entrySet().iterator();
        List<String> strings = CollUtil.newArrayList();
        while (iterator.hasNext()) {
            Map.Entry<String, String> next = iterator.next();
            strings.add(next.getValue());
        }
        return String.join(",", strings);
    }

    @Override
    public Boolean updateShareExpressDelivery(String orderNo, Integer userId) {
        LambdaUpdateWrapper<Share> updateWrapper = Wrappers.lambdaUpdate(Share.class);
        updateWrapper.set(Share::getStatus, BizSharedOrderStatus.PENDING_VALUATION.name());
        updateWrapper.set(Share::getSubStatus, BizSharedOrderStatus.SubStatus.PENDING_EXPRESS_DELIVERY.name());
        // update 条件
        updateWrapper.eq(Share::getOrderNo, orderNo);
        updateWrapper.eq(Share::getStatus, BizSharedOrderStatus.PENDING_SHIPMENT.name());
        updateWrapper.eq(Share::getUid, userId);
        return update(updateWrapper);
    }

    @Override
    public Boolean updateShareEvaluationTime(String orderNo, LocalDateTime start, LocalDateTime end, Integer userId) {
        LambdaUpdateWrapper<Share> updateWrapper = Wrappers.lambdaUpdate(Share.class);
        updateWrapper.set(Share::getArriveStoreTimeStart, start);
        updateWrapper.set(Share::getArriveStoreTimeEnd, end);
        updateWrapper.set(Share::getStatus, BizSharedOrderStatus.PENDING_VALUATION.name());
        updateWrapper.set(Share::getSubStatus, BizSharedOrderStatus.SubStatus.WAITING_USER_PICKUP.name());
        // update 条件
        updateWrapper.eq(Share::getOrderNo, orderNo);
        updateWrapper.eq(Share::getStatus, BizSharedOrderStatus.PENDING_SHIPMENT.name());
        updateWrapper.eq(Share::getUid, userId);
        return update(updateWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmReceipt(String orderNo, Integer userId) {
        // 获取用户信息
        UserInfoResponse userInfo = userService.getUserInfo();

        // 确认收货
        LambdaUpdateWrapper<Share> updateWrapper = Wrappers.lambdaUpdate(Share.class);
        updateWrapper.set(Share::getStatus, BizSharedOrderStatus.VALUATION.name());
        // update 条件
        updateWrapper.eq(Share::getOrderNo, orderNo);
        updateWrapper.eq(Share::getStatus, BizSharedOrderStatus.PENDING_VALUATION.name());
        updateWrapper.eq(Share::getUid, userId);
        update(updateWrapper);

        // 添加日志
        ShareOrderLogCreateReq req = new ShareOrderLogCreateReq();
        req.setOperateType(ShareOrderLogTypeEnums.PLAT_CONFIRM_RECEIPT.name());
        req.setOrderNo(orderNo);
        req.setOperateContent(userInfo.getNickname() + ShareOrderLogTypeEnums.PLAT_CONFIRM_RECEIPT.getText());
        shareOrderOperateLogService.addLog(req);

        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmDelivery(String orderNo, String deliveryCode, Integer userId) {
        // 验证提货码是否正确
        MerchantOrderAppointment appointment = merchantOrderAppointmentService.findAppointmentByOrderId(orderNo, MerOrderApptType.SHARED_CREATE);
        if (Objects.isNull(appointment) || !appointment.getApptNumber().equals(deliveryCode)) {
            throw new CrmebException("提货码错误");
        }

        // 获取用户信息
        UserInfoResponse userInfo = userService.getUserInfo();

        // 确认提货
        LambdaUpdateWrapper<Share> updateWrapper = Wrappers.lambdaUpdate(Share.class);
        updateWrapper.set(Share::getStatus, BizSharedOrderStatus.RETURNED.name());
        // update 条件
        updateWrapper.eq(Share::getOrderNo, orderNo);
        updateWrapper.eq(Share::getStatus, BizSharedOrderStatus.BEING_RETURNED.name());
        updateWrapper.eq(Share::getUid, userId);
        update(updateWrapper);

        // 添加日志
        ShareOrderLogCreateReq req = new ShareOrderLogCreateReq();
        req.setOperateType(ShareOrderLogTypeEnums.CONFIRM_PICKUP.name());
        req.setOrderNo(orderNo);
        req.setOperateContent(userInfo.getNickname() + ShareOrderLogTypeEnums.CONFIRM_PICKUP.getText());
        shareOrderOperateLogService.addLog(req);

        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delivery(OrderSendRequest request) {
        // 获取用户信息
        UserInfoResponse userInfo = userService.getUserInfo();

        // 调用发货接口
        orderService.send(request);

        // 添加日志
        ShareOrderLogCreateReq req = new ShareOrderLogCreateReq();
        req.setOperateType(ShareOrderLogTypeEnums.RETURNED_SHIPMENT.name());
        req.setOrderNo(request.getOrderNo());
        req.setOperateContent(userInfo.getNickname() + ShareOrderLogTypeEnums.RETURNED_SHIPMENT.getText());
        shareOrderOperateLogService.addLog(req);

        return Boolean.TRUE;
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateShareInitialEvaluationResult(UpdateInitialResultRequest request) {
        // 获取用户信息
        UserInfoResponse userInfo = userService.getUserInfo();

        // 查询是否存在
        // todo 是否只在寄送状态下才能修改初评结果
        LambdaQueryWrapper<Share> queryWrapper = Wrappers.lambdaQuery(Share.class);
        queryWrapper.eq(Share::getOrderNo, request.getOrderNo());
        Share share = getOne(queryWrapper);
        if (Objects.isNull(share)) {
            throw new CrmebException("订单不存在");
        }

        // 更新初评结果
        share.setBrand(request.getBrand());
        share.setProductType(request.getProductType());
        share.setCode(request.getCode());
        share.setQuality(request.getQuality());
        share.setParts(request.getParts());
        share.setEstimatePriceStart(request.getEstimatePriceStart());
        share.setEstimatePriceEnd(request.getEstimatePriceEnd());
        share.setDescription(request.getDescription());
        share.setStatus(request.getStatus());
        share.setUpdateTime(LocalDateTime.now());
        updateById(share);

        if (Objects.isNull(share.getEstimatePriceStart())) {
            // 添加提交初评日志
            ShareOrderLogCreateReq req = new ShareOrderLogCreateReq();
            req.setOperateType(ShareOrderLogTypeEnums.SUBMIT_EVALUATION.name());
            req.setOrderNo(request.getOrderNo());
            req.setOperateContent(userInfo.getNickname() + ShareOrderLogTypeEnums.SUBMIT_EVALUATION.getText());
            shareOrderOperateLogService.addLog(req);

        } else {
            // 添加修改日志
            ShareOrderLogCreateReq req = new ShareOrderLogCreateReq();
            req.setOperateType(ShareOrderLogTypeEnums.MODIFY_EVALUATION.name());
            req.setOrderNo(request.getOrderNo());
            req.setOperateContent(userInfo.getNickname() + ShareOrderLogTypeEnums.MODIFY_EVALUATION.getText());
            shareOrderOperateLogService.addLog(req);

        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateShareFinalEvaluationResult(UpdateFinalResultRequest request) {
        // 获取用户信息
        UserInfoResponse userInfo = userService.getUserInfo();

        // 查询是否存在
        LambdaQueryWrapper<Share> queryWrapper = Wrappers.lambdaQuery(Share.class);
        queryWrapper.eq(Share::getOrderNo, request.getOrderNo());
        Share share = getOne(queryWrapper);
        if (Objects.isNull(share)) {
            throw new CrmebException("订单不存在");
        }

        // 提交终评结果
        share.setEstimatePriceFinal(new BigDecimal(request.getEstimatePrice()));
        share.setDescription(request.getDescription());
        share.setStatus(request.getStatus());
        share.setUpdateTime(LocalDateTime.now());
        updateById(share);

        if (Objects.isNull(share.getEstimatePriceStart())) {
            // 添加提交终评日志
            ShareOrderLogCreateReq req = new ShareOrderLogCreateReq();
            req.setOperateType(ShareOrderLogTypeEnums.SUBMIT_FINAL_EVALUATION.name());
            req.setOrderNo(request.getOrderNo());
            req.setOperateContent(userInfo.getNickname() + ShareOrderLogTypeEnums.SUBMIT_EVALUATION.getText());
            shareOrderOperateLogService.addLog(req);

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateShareEstimatePrice(String orderNo, String estimatePrice) {
        // 获取用户信息
        UserInfoResponse userInfo = userService.getUserInfo();
        // 获取供享订单信息
        LambdaQueryWrapper<Share> queryWrapper = Wrappers.lambdaQuery(Share.class);
        queryWrapper.eq(Share::getOrderNo, orderNo);
        Share share = getOne(queryWrapper);
        if (Objects.isNull(share)) {
            throw new CrmebException("订单不存在");
        }
        // 更新预估价格
        share.setEstimatePriceFinal(new BigDecimal(estimatePrice));
        updateById(share);
        // 添加修改日志
        ShareOrderLogCreateReq req = new ShareOrderLogCreateReq();
        req.setOperateType(ShareOrderLogTypeEnums.MODIFY_FINAL_EVALUATION.name());
        req.setOrderNo(orderNo);
        req.setOperateContent(userInfo.getNickname() + ShareOrderLogTypeEnums.MODIFY_FINAL_EVALUATION.getText());
        shareOrderOperateLogService.addLog(req);
        return Boolean.TRUE;
    }

    @Override
    public List<LogisticsResultVo> getLogistics(String orderNo) {
        if (StringUtils.isBlank(orderNo)) {
            throw new CrmebException("单号不能为空");
        }

        return orderInvoiceService.findTraceByOrderNoAndLastTraceOnly(orderNo);

//        logisticService.info()
        // todo 需确认调用 order_invoice 获取express_no 再调logisticService.info  还是直接从logisticService方法中获取
    }

    @Override
    public void estimateConfirm(String orderNo, Integer userId) {
        // 将订单状态修改成已完成
        LambdaQueryWrapper<Share> queryWrapper = Wrappers.lambdaQuery(Share.class);
        queryWrapper.eq(Share::getOrderNo, orderNo);
        queryWrapper.eq(Share::getUid, userId);
        Share share = getOne(queryWrapper);
        if (Objects.isNull(share)) {
            throw new CrmebException("订单不存在");
        }
        // 已经完成
        share.setStatus(BizSharedOrderStatus.COMPLETED.name());
        share.setSubStatus("");
        // 获取图片
        BizImg bizImg = bizImgService.getOneByBizId(BizTypeEnum.SHARE.getType(), share.getId(), RecyclePositionEnums.POSITIVE);
        // 获取用户信息
        UserInfoResponse userInfo = userService.getUserInfo();
        // 一起提交事务
        transactionTemplate.execute(e -> {
            String path = Objects.isNull(bizImg) ? "" : bizImg.getPath();
            // 给用户添加 额度
            quotaManager.addQuota(userId, share.getEstimatePriceFinal(), orderNo, ShareOrderLogTypeEnums.SUBMIT_FINAL_EVALUATION.name(), path, ShareOrderLogTypeEnums.SUBMIT_FINAL_EVALUATION.getText());
            // 给用户添加 雅识
            if (Objects.equals(share.getShareMode(), BizShareModeEnum.SUPPORT_VALUE.getCode())) {
                shareProfitManager.shareProfitInitAndConfirm(userId, orderNo, path, share.getEstimatePriceFinal(), share.getEstimatePriceFinal(), ShareProfitSceneEnums.PRODUCT_RECYCLE_SALE);
            }
            // 保存订单
            updateById(share);
            // 保存操作日志
            shareOrderOperateLogService.addLog(orderNo, ShareOrderLogTypeEnums.CONFIRM_FINAL_EVALUATION, userInfo.getNickname());
            return true;
        });
    }

    @Override
    public Boolean updateSubStatusByOrderNo(String orderNo, BizSharedOrderStatus.SubStatus subStatus) {
        LambdaUpdateWrapper<Share> updateWrapper = Wrappers.lambdaUpdate(Share.class);
        updateWrapper.set(Share::getSubStatus, subStatus.name());
        // update 条件
        updateWrapper.eq(Share::getOrderNo, orderNo);
        return update(updateWrapper);
    }

    @Override
    public Boolean updateByEntity(Share share) {
        return updateById(share);
    }

    @Override
    public void returnDeliveryConfirm(String orderNo) {
        Share share = getByOrderNo(orderNo);
        share.setSubStatus(BizSharedOrderStatus.SubStatus.RETURNED_EXPRESS_CONFIRM.name());
        updateByEntity(share);
    }
}
